'''
'''
import sys
import logging                                                                  # запись логов

from datetime import date, timedelta

from modules.connmysql import get_db_mysql
from modules.login import get_user
from modules.moduledesigner import ModuleDesigner

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtSql import *

# sys.path.append('c:\PyLib')


def field_column(model):
    """ Создание словаря для QSqlQueryModel.
    Ключ - имя поля, значение - номер столбца."""
    D = {}
    for i in range(model.columnCount()):
        D[model.record().fieldName(i)] = i
    return D


class MainForm(QWidget):
    """
    В процессе исполнения кода все виджеты формы создаются как локальные переменные.
    Затем закладываются в контейнеры виждеты. Вся итоговая структура локальных
    сохраняется оператором self.setLayout(vbox). Чтобы иметь доступ к элементам
    класса, используем self там, где необходимо.
    """

    def __init__(self, parent=None):
        super().__init__()
        self.initUI()
    
    def initUI(self):
    
        # ВКЛАДКИ
        self.job_tab = JobTable()
        
        """ Размещение на виджете через QVBoxLayout."""
        vbox = QVBoxLayout()
        vbox.addWidget(self.job_tab)
        self.setLayout(vbox)

        # self.startTimer(60000)                                                  # 60 секунд

    def timerEvent(self,  event):
        """ Рефрешь по таймеру для текущей вкладки."""
        
        self.tab_changed(self.tab.currentIndex())
        query = QSqlQuery()
        query.exec("SELECT rec_id FROM orders.store "
            "WHERE (date_start IS NULL) AND (data_ready = 1)")
        if query.size():
            return
        self.tray_icon = QSystemTrayIcon()
        self.tray_icon.setIcon(QIcon('pict\\order.ico'))
        self.tray_icon.show()
        self.tray_icon.showMessage("ОРДЕР", "Есть невыполненные задания.", 
            QSystemTrayIcon.Information, 10000)


class JobTable(QWidget):

    ''' Вкладка для отображения "своих" заказов во всех состояниях.'''
    def __init__(self, parent=None):
        super().__init__()

        self.setup_ui()
        self.init()


    def setup_ui(self):

        """ КНОПКА """
        btn_ = QPushButton(" УПРАВЛЕНИЕ ")
        # btn_refresh_order.clicked.connect(self.refresh_order)

        """ ТАБЛИЦА. События: двойной клик и контекстное меню. """
        self.view = QTableView()
        self.view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.view.doubleClicked.connect(self.double_clik)
        self.view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.view.customContextMenuRequested.connect(self.shortcut_menu)

        hbox = QHBoxLayout()
        hbox.addWidget(btn_)
        hbox.addStretch()

        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addWidget(self.view)
        self.setLayout(vbox)


    def init(self):

        global column

        """ МОДЕЛЬ """
        self.model = OrderModel()                                                # создаём для неё модель данных
        sql = (
            "SELECT job, date_order, quickly, designer, customer, proportions, rec_id "
            "FROM store "
            "WHERE data_ready = 1 AND date_finish is null "
            "ORDER BY quickly DESC, date_order ASC;")
        self.model.setQuery(sql)
        if self.model.lastError().isValid ():
            logging.critical('TabModel: {}'.format( self.model.lastError().text()))
            quit()
        column = field_column(self.model)
        """ ЗАГОЛОВКИ ТАБЛИЦЫ """
        self.model.setHeaderData(column["time_exec"], Qt.Horizontal, 'Время')
        self.model.setHeaderData(column["job"], Qt.Horizontal, 'Задание')
        self.view.setModel(self.model)

        # for column in range(5, self.model.record().count()):
            # self.view.setColumnHidden(column, True)


    def double_clik(self, item):
        # ВЫПОЛНИТЬ ВЫДЕЛЕННУЮ ЗАПИСЬ
        
        """ Берём ключевое поле таблицы."""
        row = item.row()
        rec_id = self.model.record(row).value('rec_id')
        """ Сразу захватить заказ функцией set_designer."""
        query = QSqlQuery()
        query.exec("SELECT set_designer({},{});".format(rec_id, user.rec_id))
        query.next()
        answer = query.value(0)
        """ Если nodata - нет готовности заказа. """
        if answer == 'nodata':
            QMessageBox.warning(self,"ЗАКАЗ НЕ ГОТОВ",
                "Нужно выбрать заказ готовый к исполнению.")
            return
        """ Возвращена фамилия дизайнера."""
        if answer:
            QMessageBox.warning(self,"УЖЕ ВЫПОЛНЯЕТСЯ",
                "Поскольку этот заказ уже выполняет дизайнер: {}, то нужно выбрать другой заказ.".format(answer))
            return
        """ Открыть запись в отдельной форме. Передать управление в форму.
        После закрытия формы сделать рефрешь таблицы."""
        module = ModuleDesigner(main_form, rec_id)
        module.exec_()
        self.model.setQuery(self.model.query().lastQuery())


    def shortcut_menu(self, pos):
        #
        """ КОНТЕКСТНОЕ МЕНЮ. Создаём и запускаем"""
        menu = QMenu(self)
        menu.addAction("Сменить дизайнера", self.chage_designer)
        menu.exec_(QCursor.pos())

    def chage_designer(self):
        # СМЕНИТЬ ДИЗАЙНЕРА
        """ Номер строки (= номеру записи в модели) берём из таблицы. По номеру 
        записи находим значение ключевого поля."""
        row_tab = self.view.currentIndex().row()                              
        rec_id = self.model.record(row_tab).value('rec_id')
        
        query = QSqlQuery()
        query.exec("SELECT designer FROM orders.store WHERE rec_id = {}".format(rec_id))
        query.next()
        designer = query.value(0)
        if not designer:
            QMessageBox.warning(self,"ЗАКАЗ НЕ ВЫПОЛНЯЕТСЯ",
                "Дизайнера можно поменять только у заказа, который начали выполнять.")
            return
        if designer == user.rec_id:
            QMessageBox.warning(self,"ЗАКАЗ НЕ ВЫПОЛНЯЕТСЯ",
                "Дизайнера можно поменять только у заказа, который начали выполнять.")
            return
        self.order_tab.model.setQuery(self.order_tab.model.query().lastQuery())


class OrderModel(QSqlQueryModel):

    def __init__(self, parent=None):
        super().__init__()                                                      # запускаем init родительского класса

        self.green = QColor.fromRgb(193, 255, 193)
        self.red = QColor.fromRgb(255, 215, 215)


    def data(self, item, role):
        """ Передается элемент (QModelIndex) который прорисовывается и роль. """

        value = super(TaskModel, self).data(item, role)                         
        row = item.row()

        # ОТОБРАЖАЕМАЯ ИНФОРМАЦИЯ
        if role == Qt.DisplayRole:

            """ СТАТУС."""
            if item.column() == self.record().indexOf("status"):                # статус заказа
                if self.record(row).value('date_finish'):
                    value = 'ГОТОВ'
                if not self.record(row).value('data_ready'):
                    value = 'ЗАБЫТЫЙ'
                if self.record(row).value('data_ready') and not self.record(row).value('date_start'):
                    value = 'В ОЧЕРЕДИ'
                if self.record(row).value('date_start') and not self.record(row).value('date_finish'):
                    value = 'ВЫПОЛНЯЕТСЯ'

            """ ТИП."""
            if item.column() == self.record().indexOf("job"):                   # тип заказа
                if value == 0:
                    value = 'модуль'
            """ ВАЖНОСТЬ."""
            if item.column() == self.record().indexOf("quickly"):               # важность
                if value == 1:
                    value = 'СРОЧНО'
                else:
                    value = ''
            """ МЕНЕДЖЕР."""
            if item.column() == self.record().indexOf("customer"):              
                if value in user_dict:
                    value = user_dict[value]
                else:
                    value = ''
            """ ДИЗАЙНЕР."""
            if item.column() == self.record().indexOf("designer"):              
                if value in user_dict:
                    value = user_dict[value]
                else:
                    value = ''

        # ВЫРАВНИВАНИЕ
        if role == Qt.TextAlignmentRole:
            if item.column() == 2:
                return int(Qt.AlignRight | Qt.AlignVCenter)
            else:
                return int(Qt.AlignCenter | Qt.AlignVCenter)

        # ЦВЕТ ТЕКСТА
        if role == Qt.TextColorRole:
            if item.column() == self.record().indexOf("status"):
                if self.record(row).value('date_finish'):
                    return QColor(Qt.blue)
                if (self.record(row).value('date_start')) and (not self.record(row).value('date_finish')):
                    return QColor(Qt.green)
            # if item.column() == self.record().indexOf("status"):
                # return QColor(Qt.blue)
            if item.column() == self.record().indexOf("quickly"):
                return QColor(Qt.red)

        # ЦВЕТ ФОНА
        # if role == Qt.BackgroundRole:
            # status = ''
            # if self.record(row).value('data_ready'):
                # status = 'Забытый'
            # row = index.row()
            # if (self.record(row).value('date_start') and
                # not self.record(row).value('date_finish')):
                # return QBrush(self.green)
            # if (self.record(row).value('data_ready') and
                # not self.record(row).value('date_start')):
                # return QBrush(self.red)

        return value


class ReadyTab (QWidget):

    def __init__(self, parent=None):
        super().__init__()                                                      # запускаем init родительского класса

        self.setup_ui()
        self.init()

    def setup_ui(self):

        self.view = QTableView()
        self.view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        vbox = QVBoxLayout()
        vbox.addWidget(self.view)
        self.setLayout(vbox)

    def init(self):

        self.model = OrderModel()                                               # создаём для неё модель данных
        sql = (
            "SELECT date_order, num_asu_new, customer, designer, rec_id "
            "FROM store "
            "WHERE (date_finish IS NOT NULL) AND (DATEDIFF(NOW(),date_finish) < 1) "
            "ORDER BY date_order ASC")
        self.model.setQuery(sql)
        if self.model.lastError().isValid ():
            logging.critical('TabModel: {}'.format( self.model.lastError().text()))
            quit()
        column = field_column(self.model)

        """ ЗАГОЛОВКИ ТАБЛИЦЫ тип менеджер асу дизайнер время срочно"""
        self.model.setHeaderData(column["date_order"], Qt.Horizontal, 'Дата')
        self.model.setHeaderData(column["num_asu_new"], Qt.Horizontal, '№ АСУ')
        self.model.setHeaderData(column["customer"], Qt.Horizontal, 'Менеджер')
        self.model.setHeaderData(column["designer"], Qt.Horizontal, 'Дизайнер')
        self.view.setModel(self.model)


class OrderModel(QSqlQueryModel):

    def __init__(self, parent=None):
        super().__init__()                                                      # запускаем init родительского класса

        self.green = QColor.fromRgb(193, 255, 193)
        self.red = QColor.fromRgb(255, 215, 215)


    def data(self, item, role):
        """ Передается элемент (QModelIndex) который прорисовывается и роль. """

        value = super(OrderModel, self).data(item, role)                        # Returns the value for the specified item and role.

        # ОТОБРАЖАЕМАЯ ИНФОРМАЦИЯ
        if role == Qt.DisplayRole:

            row = item.row()
            """ СТАТУС."""
            if item.column() == self.record().indexOf("status"):                # статус заказа
                if not self.record(row).value('data_ready'):
                    value = 'ЗАБЫТЫЙ'
                if self.record(row).value('data_ready') and not self.record(row).value('date_start'):
                    value = 'В ОЧЕРЕДИ'
                if self.record(row).value('date_start') and not self.record(row).value('date_finish'):
                    value = 'ВЫПОЛНЯЕТСЯ'
                if self.record(row).value('date_finish'):
                    value = 'ГОТОВ'

            """ ТИП."""
            if item.column() == self.record().indexOf("job"):                   # тип заказа
                if value == 0:
                    value = 'модуль'
            """ ВАЖНОСТЬ."""
            if item.column() == self.record().indexOf("quickly"):               # важность
                if value == 1:
                    value = 'СРОЧНО'
                else:
                    value = ''
            """ МЕНЕДЖЕР."""
            if item.column() == self.record().indexOf("customer"):              
                if value in user_dict:
                    value = user_dict[value]
                else:
                    value = ''
            """ ДИЗАЙНЕР."""
            if item.column() == self.record().indexOf("designer"):              
                if value in user_dict:
                    value = user_dict[value]
                else:
                    value = ''

        # ВЫРАВНИВАНИЕ
        if role == Qt.TextAlignmentRole:
            if item.column() == 2:
                return int(Qt.AlignRight | Qt.AlignVCenter)
            else:
                return int(Qt.AlignCenter | Qt.AlignVCenter)

        # ЦВЕТ ТЕКСТА
        if role == Qt.TextColorRole:
            if item.column() == self.record().indexOf("status"):
                return QColor(Qt.blue)
            if item.column() == self.record().indexOf("quickly"):
                return QColor(Qt.red)

        # ЦВЕТ ФОНА
        # if role == Qt.BackgroundRole:
            # status = ''
            # if self.record(row).value('data_ready'):
                # status = 'Забытый'
            # row = index.row()
            # if (self.record(row).value('date_start') and
                # not self.record(row).value('date_finish')):
                # return QBrush(self.green)
            # if (self.record(row).value('data_ready') and
                # not self.record(row).value('date_start')):
                # return QBrush(self.red)

        return value


def main():

    global user # ссылка на инфу по юзеру
    global db # ссылка на БД
    global user_dict # 
    global main_form
    
    app = QApplication(sys.argv)
    
    logging.basicConfig(filename='scheduler.log',level=logging.DEBUG,
        format = u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s %(message)s')
        
    """ Соединение с БД."""
    db = get_db_mysql("scheduler.ini")
    if not db:
        print("нет соединения")
        quit()
    """ Авторизация пользователя."""
    user = get_user("scheduler.ini")
    if not user:
        quit()

    """ Словарь пользователей. Ключ - код, содержимое фамилия. """
    query = QSqlQuery(db)
    query.exec("SELECT rec_id, surname FROM users;")           
    user_dict = {}
    while query.next():
        user_dict[query.value(0)] = query.value(1)

    """установим желтый цвет в качестве фона во всех объектах QLine Edit приложения. Этого можно достичь следующим образом:
    qApp->setStyleSheet("QLineEdit { background-color: yellow }");"""
    # app.setStyleSheet("QWidget { font-size: 14px }")
    """ Создаем материнское окно."""
    main_form = MainForm()                                                        
    main_form.setWindowTitle("ОРДЕР")
    main_form.setWindowIcon(QIcon("pict\\prog.ico"))
    main_form.resize(700, 600)
    main_form.show()                                                               
    sys.exit(app.exec_())                                                      
    
    
if __name__ == '__main__':                                               
    main()